package view;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import model.FileParser;
import model.Manuscript;
import model.Recommendation;
import model.Review;
import model.State;
import model.Status;

/**
 * Class to create a PCPanel.
 * @author Sarah George
 * @version Autumn 2012
 */
@SuppressWarnings("serial")
public class PCPanel extends JPanel implements Observer {
	
	/**
	 * Field to hold current state.
	 */
	private State my_state;
	
	/**
	 * Field to hold the FileParser.
	 */
	private FileParser my_fp;
	
	/**
	 * Field to hold array of papers.
	 */
	private Manuscript[] my_papers;
	
	/**
	 * Field to hold a paper's name.
	 */
	private String paper_name;
	
	/**
	 * Field to hold the review combobox.
	 */
	private JComboBox<Review> my_rev_comboBox;
	
	/**
	 * Field to hold the Rev List for the rev comboBox.
	 */
	private RevListener my_revlist;
	
	/**
	 * Field to hold the status comboBox.
	 */
	private JComboBox<Status> my_status_comboBox;
	
	/**
	 * Field to hold the Status Listener for the status combobox.
	 */
	private StatusListener my_statList;
	
	/**
	 * Field to hold array oc column names.
	 */
	private static final String[] headTitles = new String[] 
			{ "Title","Open Paper","Open Rec","Rec Status", "Status","PC Decision","SPC Assigned","Assign" };
	
	/**
	 * Field to store the number of columns needed.
	 */
	private static final int cols = headTitles.length;
	
	/**
	 * Constructor for a PCPAnel.
	 * @param the_state the current state
	 */
	public PCPanel(State the_state) {
		super();
		my_state = the_state;
		my_fp = my_state.getParser();
		my_fp.addObserver(this);
		setup();
	}
	
	/**
	 * Method to setup the PCPanel.
	 */
	public void setup() {
		GridLayout exp_layout = new GridLayout(0,cols);
		setLayout(exp_layout);
		int conf_id = my_state.getConference().getConfID();
		my_papers = my_fp.getPapersByConference(conf_id);
		
		//PREPARE OBJECTS TO DRAW
		if (my_papers.length > 0) //draw headers
		{
			JLabel[] headers = new JLabel[cols];
			for(int i = 0; i < cols; i++)
			{
				headers[i] = new JLabel(headTitles[i]);
				headers[i].setHorizontalAlignment(JLabel.CENTER);
				add(headers[i]);
			}
		}
		
		for (int i = 0; i < my_papers.length; i++) {
			paper_name = my_papers[i].getMy_title();
			JLabel pn = new JLabel(paper_name);
			OpenPaperAction opa = new OpenPaperAction(my_papers[i]);
			JButton open = new JButton(opa);
			
			my_rev_comboBox = new JComboBox<Review>();
			my_rev_comboBox.setVisible(false);
			my_revlist = new RevListener();
			my_status_comboBox = new JComboBox<Status>();
			my_status_comboBox.setVisible(false);
			my_statList = new StatusListener(my_papers[i], my_fp);
			JLabel curr_status = new JLabel(my_papers[i].getMy_status().toString());
			
			this.add(pn);  //1
			this.add(open);  //2
			this.add(my_rev_comboBox);
			
			getReviews(my_papers[i]);
			getRec(my_papers[i]);
			
			this.add(curr_status);
			if (my_papers[i].getMy_status().ordinal() >= 3) {
				this.add(my_status_comboBox);
				getStatus(my_papers[i]);
			} else {
				this.add(new JLabel("No Decision"));
			}
			
			int spc_id = my_papers[i].getMy_spc();
			
			String spc_name;
			
			if (spc_id == FileParser.NEW_ELEMENT) {
				spc_name = "N/A";
			} else {
				spc_name = my_fp.getUserWithID(spc_id).getName();
			}
			
			this.add(new JLabel(spc_name));
			
			AssignPaperToSPCAction assign_spc = new AssignPaperToSPCAction(my_papers[i], my_state);
			this.add(new JButton(assign_spc));
		}
	}

	/**
	 * Method to populate the review combobox for a paper.
	 * @param paper the paper.
	 */
	public void getReviews(Manuscript paper) {
		my_rev_comboBox.removeActionListener(my_revlist);  
		my_rev_comboBox.removeAllItems(); 
		System.out.println("Paper id" + paper.getMy_id());
		Review[] reviews = my_fp.getReviewsByPaperID(paper.getMy_id());
		if (reviews != null && reviews.length >= 1) {
			for (int i = 0; i < reviews.length; i++) {
				my_rev_comboBox.addItem(reviews[i]);
			}
			my_rev_comboBox.setVisible(true);
			my_rev_comboBox.addActionListener(my_revlist);
			this.validate();
		}
	}
	
	/**
	 * Method to display a recommendation for a paper.
	 * @param the_paper the paper.
	 */
	public void getRec(Manuscript the_paper) {
		Recommendation[] rec = my_fp.getRecommendationByPaperID(the_paper.getMy_id());
		if (rec.length > 0)
		{
			OpenRecAction ora = new OpenRecAction(rec[0]);
			JButton brec = new JButton(ora);
			this.add(brec);
		} else {
			this.add(new JLabel("Rec Pending"));
		}
	}
	
	/**
	 * Method to populate and display the combobox of status decisions for a paper.
	 * @param the_paper the paper.
	 */
	public void getStatus(Manuscript the_paper) {
		my_status_comboBox.removeActionListener(my_statList);  
		my_status_comboBox.removeAllItems();
		Status[] decision_status = new Status[2];
		decision_status[0] = Status.ACCEPTED;
		decision_status[1] = Status.REJECTED;
		for (int i = 0; i < decision_status.length; i++) {
			my_status_comboBox.addItem(decision_status[i]);
		}
		my_status_comboBox.setVisible(true);
		my_status_comboBox.addActionListener(my_statList);
		this.validate();
	}

	private void clear()
	{
		this.removeAll();
		this.repaint();
	}
	
	/**
	 * Method to update the PCPanel.
	 * @param o the observable
	 * @param arg the object that called Notify Observer.
	 */
	@Override
	public void update(Observable o, Object arg) {
		this.clear();
		this.setup();
		this.validate();
		this.repaint();	
	}
}//End class PCPanel.